home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / comm / bbs / cit_src_7H21.lha / netcall.c < prev    next >
C/C++ Source or Header  |  1997-08-21  |  30KB  |  1,193 lines

  1. /*
  2. *       netcall.c
  3. *
  4. * Networking call functions.
  5. */
  6. /*
  7. *       history
  8. *
  9. * 86Aug20 HAW  History not maintained due to space problems.
  10. */
  11. #include "ctdl.h"
  12. #include "math.h"
  13. /*
  14. *       contents
  15. *
  16. */
  17. char                    inReceive;
  18. NetInfo     NetStyle;
  19. extern char   RecMassTransfer;
  20. extern char             *SR_Sent;
  21. extern char             *pollCall;
  22. extern FILE             *netMisc;
  23. extern FILE             *netLog;
  24. extern AN_UNSIGNED      RecBuf[SECTSIZE + 5];
  25. extern int              counter;
  26. extern int              callSlot;
  27. extern label            callerName, callerId;
  28. char                    checkNegMail;
  29. extern char             processMail;
  30. extern char   MassTransferSent;
  31. char             normId(), getNetMessage();
  32. AN_UNSIGNED      inp();
  33. extern CONFIG    cfg;            /* Lots an lots of variables    */
  34. extern logBuffer logBuf;         /* Person buffer                */
  35. extern logBuffer logTmp;         /* Person buffer                */
  36. extern aRoom     roomBuf;        /* Room buffer                  */
  37. extern rTable    *roomTab;
  38. extern PROTO_TABLE Table[];
  39. extern int TransProtocol;
  40. extern MessageBuffer   msgBuf;
  41. extern NetBuffer netBuf, netTemp;
  42. extern NetTable  *netTab;
  43. /* extern SListBase FwdAliasii; */
  44. extern int       thisNet;
  45. extern char      onConsole;
  46. extern char      loggedIn;       /* Is we logged in?             */
  47. extern char      outFlag;        /* Output flag                  */
  48. extern char      haveCarrier;    /* Do we still got carrier?     */
  49. extern char      modStat;        /* Needed so we don't die       */
  50. extern char      TrError;
  51. extern int       thisRoom;
  52. extern char      netDebug;
  53. extern char      logNetResults;
  54. extern char  *DomainFlags;
  55. extern long ByteCount, EncCount;
  56. char *chMailTemplate = "chkMail.$$$";
  57. extern long  char_in, char_out; /* send/recieve character counts*/
  58. long start_time;                /* total time of session */
  59. /*
  60. * caller()
  61. *
  62. * This function is called when we've been called and have to handle the
  63. * caller.  We have to stabilize the call and then manage all requests
  64. * the caller makes of us.
  65. */
  66. void caller()
  67.   {
  68.   ITL_InitCall();             /* initialize the ITL layer */
  69.   RecMassTransfer = FALSE;
  70.   memset(SR_Sent, 0, SHARED_ROOMS);
  71.   inReceive = FALSE;
  72.   processMail = FALSE;
  73.   checkNegMail = FALSE;
  74.   SpecialMessage("Status:Net Carrier");
  75.   if( logNetResults && netDebug )splitF(netLog, "Have Carrier\n");
  76.   caller_stabilize();
  77.   if (!haveCarrier) return ;  /* Abort */
  78.   if( logNetResults && netDebug )splitF(netLog, "Stabilized\n");
  79.   SpecialMessage("Status:Net Session");
  80.   char_in = char_out = 0;
  81.   start_time = Set_Timer(0);
  82.   sendId();
  83.   if (!haveCarrier) return ;  /* Abort */
  84.   if (!netBuf.nbflags.MassTransfer)
  85.   ITL_optimize(TRUE);   /* try for better protocol */
  86.   sendStuff(FALSE, TRUE);
  87.   startTimer(WORK_TIMER);
  88.   while (gotCarrier() && chkTimeSince(WORK_TIMER) < 10) ;
  89.   killConnection();
  90.   if( logNetResults )splitF(netLog, "\nFinished with %s @%s\n", netBuf.netName, Current_Time());
  91.   Compute_Data(netBuf.netName);
  92.   doResults();
  93.   SpecialMessage("Status:Net Completed");
  94.  
  95.   }
  96. /*
  97. * sendStuff()
  98. *
  99. * This function handles being the sender of information (sending role).
  100. */
  101. void sendStuff(char reversed, char SureDoIt)
  102.   {
  103.   extern int RouteToDirect;
  104.   if (SureDoIt && callSlot != ERROR)
  105.     {
  106.     MassTransferSent = FALSE;
  107.     SendPwd();
  108.     if (!haveCarrier) return ;  /* Abort */
  109.     if (netBuf.nbflags.HasRouted)    RouteOut();
  110.     if (!haveCarrier) return ;  /* Abort */
  111.     if (!netBuf.nbflags.Stadel) DomainOut(FALSE);
  112.     if (!haveCarrier) return ;  /* Abort */
  113.     if (netBuf.nbflags.normal_mail ||
  114.     RouteToDirect != -1 ||
  115.     (netBuf.nbflags.Stadel && DomainFlags[thisNet]))
  116.       {
  117.       sendMail();
  118.       if (!haveCarrier) return ;  /* Abort */
  119.       checkMail();
  120.  
  121.       }
  122.     if (!haveCarrier) return ;  /* Abort */
  123.     if (!HasPriorityMail(thisNet))
  124.       {
  125.       if (netBuf.nbflags.room_files)
  126.       askFiles();
  127.       if (!haveCarrier) return ;  /* Abort */
  128.       sendSharedRooms();
  129.       if (!haveCarrier) return ;  /* Abort */
  130.       if (netBuf.nbflags.send_files)
  131.       doSendFiles();
  132.       if (!haveCarrier) return ;  /* Abort */
  133.       roleReversal(reversed);
  134.  
  135.       }
  136.  
  137.     }
  138.   sendHangUp();
  139.   pollCall[thisNet]--;        /* Don't set polled flag unless stable call */
  140.  
  141.   }
  142. /*
  143. * SendPwd()
  144. *
  145. * This function sends the system password if necessary.
  146. */
  147. void SendPwd()
  148.   {
  149.   struct cmd_data cmds;
  150.   if (netBuf.TheirPwd[0] != 0)
  151.     {
  152.     /* only send if need to -- gets */
  153.     zero_struct(cmds);              /* us around a bug in pre net 1.10*/
  154.     strCpy(cmds.fields[0], netBuf.TheirPwd);        /* versions     */
  155.     cmds.command = SYS_NET_PWD;
  156.     sendNetCommand(&cmds, "system pwd");
  157.  
  158.     }
  159.  
  160.   }
  161. /*
  162. * roleReversal()
  163. *
  164. * This function handles the role reversal request.
  165. */
  166. void roleReversal(char reversed)
  167.   {
  168.   struct cmd_data cmds;
  169.   if (reversed) return ;
  170.   if (!netBuf.nbflags.local && !netBuf.nbflags.spine) return ;
  171.   if( logNetResults && netDebug )splitF(netLog, "Reversing roles\n");
  172.   zero_struct(cmds);
  173.   cmds.command = ROLE_REVERSAL;
  174.   if (!sendNetCommand(&cmds, "role reversal"))
  175.   return;
  176.   rcvStuff(TRUE);
  177.   pause(50);   /* wait a second */
  178.   if (gotCarrier())
  179.   reply(GOOD, "");/* this replies GOOD to the HANGUP terminating the */
  180.   /* role reversal.  NOTE: STadel doesn't follow the */
  181.   /* spec in this regard - it just dumps carrier     */
  182.  
  183.   }
  184. /*
  185. * caller_stabilize()
  186. *
  187. * This function tries to stabilize the call -- baud is already set.
  188. */
  189. void caller_stabilize()
  190.   {
  191.   int tries, x1, x2, x3;
  192.   extern char hst;
  193.   /* regrettable initialization */
  194.   for (tries = 0; tries < SHARED_ROOMS; tries++) resetNeedsProcessing(tries);
  195.   putNet(thisNet, &netBuf);
  196.   pause(50);                                  /* delay for a little bit */
  197.   while (MIReady())   inp();                  /* Clear garbage        */
  198.   startTimer(USER_TIMER);                     /* this is safe */
  199.   x3 = 0;
  200.   for (tries = 0; (chkTimeSince(USER_TIMER) < 20l || tries < 40) &&
  201.   gotCarrier() ; tries++)
  202.     {
  203.     outMod(7);
  204.     outMod(13);
  205.     outMod(69);
  206.     for (  startTimer(WORK_TIMER); chkTimeSince(WORK_TIMER) < 2l && !MIReady();) ;
  207.     if (MIReady())
  208.       {
  209.       x1 = receive(2);
  210.       x2 = receive(2);
  211.       if (x2 != ERROR) x3 = receive(2);
  212.       if (x1 == 248 && x2 == 242 && x3 == 186)
  213.         {
  214.         outMod(ACK);
  215.         /* ok, we've seen at high speed some overrun problems, so ... */
  216.         do
  217.           {
  218.           x1 = receive(2);
  219.  
  220.           }
  221.         while (x1 == 248 || x1 == 242 || x1 == 186);
  222.         ModemPushBack(x1);
  223.         return;
  224.  
  225.         }
  226.       else
  227.         {
  228.         if ( ( x1 == 242 || x1 == 186 || x1 == 248 )
  229.         || ( x2 == 242 || x2 == 186 || x2 == 248 )
  230.         || ( x3 == 242 || x3 == 186 || x3 == 248 ) )  /* all combinations */
  231.           {
  232.           /* real close, so let's catch our breath */
  233.           while (receive(1) != ERROR) ;
  234.  
  235.           };
  236.  
  237.         }
  238.  
  239.       }
  240.     else
  241.       {
  242.       tries ++;  /* if we get nothing back, don't try as much, try half the number of times */
  243.  
  244.       }
  245.  
  246.     }
  247.   if( logNetResults && netDebug )splitF(netLog, "Call not stabilized:tries=%d \n",tries);
  248.   killConnection();
  249.  
  250.   }
  251. /*
  252. * sendId()
  253. *
  254. * This function sends ID to the receiver.
  255. */
  256. void sendId()
  257.   {
  258.   if (!ITL_Send(STARTUP))
  259.     {
  260.     no_good("Couldn't transfer ID to %s at startup!", TRUE);
  261.     return;
  262.  
  263.     }
  264.   mTrPrintf("%s", cfg.codeBuf + cfg.nodeId  );
  265.   mTrPrintf("%s", cfg.codeBuf + cfg.nodeName);
  266.   if (!ITL_Send(FINISH))
  267.     {
  268.     no_good("Couldn't transfer ID to %s at finish!", TRUE);
  269.     return;
  270.  
  271.     }
  272.  
  273.   }
  274. /*
  275. * sendMail()
  276. *
  277. * This function sends normal mail to receiver.
  278. */
  279. void sendMail()
  280.   {
  281.   struct cmd_data cmds;
  282.   int             nor_mail;
  283.   extern int      RouteToDirect;
  284.   if (!gotCarrier())
  285.     {
  286.     modStat = haveCarrier = FALSE;
  287.     return ;
  288.  
  289.     }
  290.   if( logNetResults && netDebug )splitF(netLog, "Sending Mail ");
  291.   zero_struct(cmds);
  292.   cmds.command = NORMAL_MAIL;
  293.   if (!sendNetCommand(&cmds, "normal mail"))
  294.   return;
  295.   if (!ITL_SendMessages())
  296.     {
  297.     no_good("Couldn't start Mail transfer to %s!", TRUE);
  298.     killConnection();
  299.     return;
  300.  
  301.     }
  302.   nor_mail = s_m_n();            /* Send normal mail     */
  303.   if (gotCarrier())
  304.   nor_mail += SendRoutedAsLocal();
  305.   if (gotCarrier() && netBuf.nbflags.Stadel)
  306.   nor_mail += DomainOut(TRUE);
  307.   ITL_StopSendMessages();
  308.   RouteToDirect = -1;         /* This is just in case */
  309.   if (gotCarrier())
  310.     {
  311.     if( logNetResults && netDebug )splitF(netLog, "(%d) (%ld => %ld bytes)\n",nor_mail,EncCount,ByteCount);
  312.     netBuf.nbflags.normal_mail = FALSE;
  313.  
  314.     }
  315.  
  316.   }
  317. /*
  318. * checkMail()
  319. *
  320. * This function handles negative acknowledgement on netMail.
  321. */
  322. void checkMail()
  323.   {
  324.   struct cmd_data cmds;
  325.   SYS_FILE fileNm;
  326.   extern char *WRITE_ANY;
  327.   if (!gotCarrier())
  328.     {
  329.     return;
  330.  
  331.     }
  332.   if( logNetResults && netDebug )splitF(netLog, "Check mail\n");
  333.   makeSysName(fileNm, chMailTemplate, &cfg.netArea);
  334.   zero_struct(cmds);
  335.   cmds.command = CHECK_MAIL;
  336.   if (!sendNetCommand(&cmds, "check mail"))
  337.     {
  338.     return;
  339.  
  340.     }
  341.   if (ITL_Receive(fileNm, FALSE, TRUE, putFLChar, fclose) == ITL_SUCCESS)
  342.   checkNegMail = TRUE;        /* Call readNegMail() later */
  343.  
  344.   }
  345. /*
  346. * readNegMail()
  347. *
  348. * This function reads and processes negative acks.
  349. */
  350. void readNegMail(char talk)
  351.   {
  352.   label author, target, context;
  353.   int whatLog;
  354.   int  sigChar;
  355.   SYS_FILE fileNm;
  356.   extern char *READ_ANY;
  357.   makeSysName(fileNm, chMailTemplate, &cfg.netArea);
  358.   if ((netMisc = safeopen(fileNm, READ_ANY)) == NULL)
  359.     {
  360.     if (talk) no_good("Couldn't open negative ack file from %s.", FALSE);
  361.     return ;
  362.  
  363.     }
  364.   getRoom(MAILROOM);
  365.   sigChar = fgetc(netMisc);
  366.   while (sigChar != NO_ERROR && sigChar != EOF && sigChar != EOF)
  367.     {
  368.     ZeroMsgBuffer(&msgBuf);
  369.     strCpy(msgBuf.mbauth, "Citadel");
  370.     getMsgStr(getNetChar, author, NAMESIZE);
  371.     getMsgStr(getNetChar, target, NAMESIZE);
  372.     getMsgStr(getNetChar, context, NAMESIZE);
  373.     switch (sigChar)
  374.       {
  375.       case NO_RECIPIENT:
  376.       strCpy(msgBuf.mbto, author);
  377.       if ((whatLog = PersonExists(author)) >= 0 &&
  378.       whatLog < cfg.MAXLOGTAB)
  379.         {
  380.         sPrintf(msgBuf.mbtext,
  381.         "Your netMail to '%s' (%s) failed because there is no such recipient on %s.",
  382.         target, context, callerName);
  383.         putMessage(&logBuf);
  384.         break;
  385.  
  386.         }
  387.       case UNKNOWN:
  388.       ZeroMsgBuffer(&msgBuf);
  389.       sPrintf(msgBuf.mbtext,
  390.       "Unknown problems with netMail: author=-%s-, target=-%s-, context=-%s-.  System was %s.",
  391.       author, target, context, netBuf.netName);
  392.       netResult(msgBuf.mbtext);
  393.       break;
  394.       case BAD_FORM:
  395.       sPrintf(msgBuf.mbtext, "Bad netMail sent to %s.", callerName);
  396.       netResult(msgBuf.mbtext);
  397.       break;
  398.       default:
  399.       sPrintf(msgBuf.mbtext, "Bad sigChar=%d.", sigChar);
  400.       netResult(msgBuf.mbtext);
  401.       break;
  402.  
  403.       }
  404.     sigChar = fgetc(netMisc);
  405.  
  406.     }
  407.   fclose(netMisc);
  408.   unlink(fileNm);
  409.  
  410.   }
  411. /*
  412. * sendSharedRooms()
  413. *
  414. * This sends all shared rooms to receiver.
  415. */
  416. static int SendRoom(SharedRoom *room, int system, int index, int roomslot,void *d);
  417. void sendSharedRooms()
  418.   {
  419.   SendFastTransfer();
  420.   EachSharedRoom(thisNet, SendRoom, SendVirtualRoom, NULL);
  421.  
  422.   }
  423. /*
  424. * EachSharedRoom()
  425. *
  426. * This does something for each shared room.
  427. */
  428. void EachSharedRoom(int system,
  429. int (*func)(SharedRoom *room, int system, int index, int roomslot, void *d),
  430. int (*virtfunc)(VirtualRoom *room, int sys, int index, int which, void *d),
  431. void *data)
  432.   {
  433.   int rover;
  434.   if (!netTab[system].ntflags.in_use) return;
  435.   if (func != NULL)
  436.     {
  437.     for (rover = 0; rover < SHARED_ROOMS; rover++)
  438.       {
  439.       if (isSharedRoom(system, rover) && roomValidate(system, rover))
  440.         {
  441.         if ((*func)(netTab[system].netTRooms + rover, system,
  442.         rover, netTabRoomSlot(system, rover), data) == ERROR)
  443.         return;
  444.  
  445.         }
  446.  
  447.       }
  448.  
  449.     }
  450.   if (virtfunc != NULL) DoVirtuals(system, virtfunc, data);
  451.  
  452.   }
  453. /*
  454. * Addressing()
  455. *
  456. * This function is responsible for deciding what sort of addressing or routing
  457. * flags should be checked for, and if the room should be sent if we are in
  458. * a network session.
  459. */
  460. void Addressing(int system, int index, char *commnd, char **send1, char **send2,
  461. char **send3, char **name, char *doit)
  462.   {
  463.   extern char *R_SH_MARK, *NON_LOC_NET, *LOC_NET;
  464.   /*
  465.   * This is more than just a trivial efficiency.  This routine can be called
  466.   * indirectly by the room editing functions.  If this happens then the
  467.   * getRoom() call would overwrite the roomBuf being used for editing.
  468.   * Therefore, we can only read in roomBuf if we don't have the right one
  469.   * in place, otherwise we lose what we just changed.
  470.   */
  471.   if (thisRoom != netTabRoomSlot(system, index))
  472.   getRoom(netTabRoomSlot(system, index));
  473.   *doit = TRUE;
  474.   *send1 = R_SH_MARK;
  475.   *send2 = *send3 = "guh";
  476.   switch (roomBuf.rbShareType)
  477.     {
  478.     case PEON:
  479.     *commnd = NET_ROOM;
  480.     *name = "Peon";
  481.     break;
  482.     case REG_HOST:          /* obsolete */
  483.     case BACKBONE:
  484.     switch (CGetMode(netTab[system].netTRooms[index].mode))
  485.       {
  486.       case PEON:
  487.       *commnd = NET_ROOM;
  488.       *send2 = NON_LOC_NET;
  489.       *name = "Peon";
  490.       break;
  491.       case ACTIVE_BACKBONE:
  492.       case REG_HOST:
  493.       if (netTab[system].ntflags.local)
  494.       *commnd = NET_ROOM;
  495.       else
  496.       *commnd = NET_ROUTE_ROOM;
  497.       *send2 = NON_LOC_NET;
  498.       *send3 = LOC_NET;
  499.       *name = "Backbone - Active";
  500.       break;
  501.       case PASS_BACKBONE:
  502.       if (!netTab[system].ntflags.local && !inReceive) *doit = FALSE;
  503.       else if (netTab[system].ntflags.local)
  504.       *commnd = NET_ROOM;
  505.       else
  506.       *commnd = NET_ROUTE_ROOM;
  507.       *send2 = NON_LOC_NET;
  508.       *send3 = LOC_NET;
  509.       *name = "Backbone - Passive";
  510.       break;
  511.       default: crashout("shared rooms: #2");
  512.  
  513.       }
  514.     break;
  515.     default: crashout("shared rooms: #1");
  516.  
  517.     }
  518.   }
  519. /*
  520. * SendRoom()
  521. *
  522. * Sends a room to the receiving system during netting.  It returns ERROR if
  523. * carrier etc is lost.
  524. */
  525. static int SendRoom(SharedRoom *room, int system, int index, int roomslot,
  526. void *d)
  527.   {
  528.   char cmd;
  529.   char doit, *s1, *s2, *s3, *name;
  530.   if (!gotCarrier())
  531.     {
  532.     modStat = haveCarrier = FALSE;
  533.     return ERROR;
  534.  
  535.     }
  536.   Addressing(system, index, &cmd, &s1, &s2, &s3, &name, &doit);
  537.   if (doit && SR_Sent[index] != 1 &&
  538.   (roomTab[roomslot].rtlastNet >  netBuf.netRooms[index].lastMess ||
  539.   GetFA(room->mode) ||
  540.   (roomTab[roomslot].rtShareType == BACKBONE &&
  541.   CGetMode(room->mode) != PEON &&  !netBuf.nbflags.local))
  542.   )
  543.     {
  544.     /**
  545.     if (cfg.BoolFlags.debug)
  546.     splitF(netLog, "Why: %s && %d[%d] && ( %ld > %ld || %d || ( %s BACKBONE && %s PEON && %s LOCAL))\n",
  547.     (doit ? "TRUE":"FALSE"), SR_Sent[index],index,
  548.     roomTab[roomslot].rtlastNet,netBuf.netRooms[index].lastMess,GetFA(room->mode),
  549.     (roomTab[roomslot].rtShareType == BACKBONE ? "" : "Not"),
  550.     (CGetMode(room->mode) != PEON ? "Not" : ""),
  551.     (netBuf.nbflags.local ? "" : "NOT"));
  552.     **/
  553.     ITL_optimize(TRUE);
  554.     findAndSend((RecMassTransfer || chkNeedsProcessing(index)) ?
  555.     NET_ROOM : cmd, s1, s2, s3, index,
  556.     RoomSend, roomTab[roomslot].rtname, RoomReceive);
  557.  
  558.     }
  559.   return TRUE;
  560.  
  561.   }
  562. /*
  563. * findAndSend()
  564. *
  565. * This function manages sending a room (virtual or normal) to the receiver,
  566. * handling both normal and route rooms, via function pointers.
  567. */
  568. void  findAndSend(int commnd, char *send1, char *send2, char *send3, int rover,
  569. int (*MsgSender)(int r, char *d1, char *d2, char *d3),
  570. label roomName, int (*MsgReceiver)(int r, char y))
  571.   {
  572.   struct cmd_data cmds;
  573.   extern MessageBuffer tempMess;
  574.   int  tempcount;
  575.   extern char *netRoomTemplate, *WRITE_ANY;
  576.   if (!gotCarrier()) return;
  577.   zero_struct(cmds);
  578.   cmds.command = commnd;
  579.   strCpy(cmds.fields[0], roomName);
  580.   if (commnd != ERROR)
  581.   if (!sendNetCommand(&cmds, "shared rooms"))
  582.     {
  583.     if (commnd == NET_ROUTE_ROOM)
  584.       {
  585.       findAndSend(NET_ROOM, send1, send2, send3, rover, MsgSender,
  586.       roomName, MsgReceiver); /* time to recurse */
  587.       return ;
  588.  
  589.       }
  590.     else
  591.       {
  592.       sPrintf(tempMess.mbtext, "%%s reports: %s (%s) commnd=%d", RecBuf+1,
  593.       roomName,commnd);
  594.       no_good(tempMess.mbtext, FALSE);
  595.       return ;
  596.  
  597.       }
  598.  
  599.     }
  600.   if (!ITL_SendMessages())
  601.     {
  602.     no_good("Couldn't start WC for room sharing: %s",
  603.     FALSE);
  604.     return;
  605.  
  606.     }
  607.   tempcount = (*MsgSender)(rover, send1, send2, send3);
  608.   ITL_StopSendMessages();
  609.   if( logNetResults && netDebug )
  610.     {
  611.     if( EncCount > 0)
  612.       splitF(netLog, "(%d) (%ld => %ld bytes)\n", tempcount, EncCount, ByteCount);
  613.     else splitF(netLog,"\n");
  614.     };
  615.   if (commnd == NET_ROUTE_ROOM)
  616.     {
  617.     (*MsgReceiver)(rover, FALSE);
  618.  
  619.     }
  620.  
  621.   }
  622. /*
  623. * RoomReceive()
  624. *
  625. * This function receives messages for a room.
  626. */
  627. int RoomReceive(int rover, char ReplyFirst)
  628.   {
  629.   recNetMessages(rover, roomBuf.rbname, netRoomSlot(rover), FALSE);
  630.   return 0;
  631.  
  632.   }
  633. /*
  634. * RoomSend()
  635. *
  636. * This function sends messages for a room.
  637. */
  638. int RoomSend(int rover, char *send1, char *send2, char *send3)
  639.   {
  640.   extern char PrTransmit;
  641.   char work[10];
  642.   int MsgCount = 0;
  643.   if( logNetResults && netDebug )splitF(netLog, "Sending %s ", roomBuf.rbname);
  644.   zero_struct(NetStyle);
  645.   NetStyle.addr1 = send1;
  646.   NetStyle.addr2 = send2;
  647.   NetStyle.addr3 = send3;
  648.   if (GetFA(netBuf.netRooms[rover].mode))
  649.     {
  650.     sPrintf(work, CACHE_END_NAME, netRoomSlot(rover));
  651.     if (SendPrepAsNormal(work, &MsgCount))
  652.     UnSetFA(netBuf.netRooms[rover].mode);
  653.  
  654.     }
  655.   NetStyle.sendfunc = sendITLchar;
  656.   /*   PrTransmit = FALSE; */
  657.   MsgCount += showMessages(NEWoNLY, FALSE, netBuf.netRooms[rover].lastMess,
  658.   NetRoute);
  659.   if (TrError == TRAN_SUCCESS)
  660.     {
  661.     SetHighValues(rover);
  662.     SR_Sent[rover] = 1;
  663.  
  664.     }
  665.   else
  666.     {
  667.     MsgCount = 0;
  668.  
  669.     }
  670.   return MsgCount;
  671.  
  672.   }
  673. /*
  674. * SetHighValues()
  675. *
  676. * This function sets the high message sent for a normal shared room after a
  677. * successful net session has (apparently) taken place.
  678. */
  679. void SetHighValues(int rover)
  680.   {
  681.   if (NetStyle.HiSent == 0l)
  682.     {
  683.     NetStyle.HiSent =
  684.     max(netBuf.netRooms[rover].lastMess,roomTab[thisRoom].rtlastMessage);
  685.  
  686.     }
  687.   netBuf.netRooms[rover].lastMess = NetStyle.HiSent;
  688.   netTab[thisNet].netTRooms[rover].lastMess = NetStyle.HiSent;
  689.  
  690.   }
  691. /*
  692. * SendPrepAsNormal()
  693. *
  694. * This function sends files prepared for cache sending as normal message files,
  695. * instead.
  696. */
  697. char SendPrepAsNormal(char *work, int *MsgCount)
  698.   {
  699.   char tempNm[3*NAMESIZE];
  700.   NetCacheName(tempNm, thisNet, work);
  701.   if ((netMisc = safeopen(tempNm, READ_ANY)) != NULL)
  702.     {
  703.     while (getMessage(getNetChar, TRUE, TRUE, TRUE))
  704.       {
  705.       (*MsgCount)++;
  706.       prNetStyle(0, sendITLchar, FALSE, "");
  707.  
  708.       }
  709.     fclose(netMisc);
  710.  
  711.     }
  712.   if (gotCarrier())
  713.     {
  714.     unlink(tempNm);
  715.     return TRUE;
  716.  
  717.     }
  718.   return FALSE;
  719.  
  720.   }
  721. /*
  722. * NetRoute()
  723. *
  724. * This is a worker function, returns TRUE if message sent.
  725. */
  726. char NetRoute(int status)
  727.   {
  728.   long temp;
  729.   if ((strncmp(msgBuf.mbaddr, NetStyle.addr1, strLen(NetStyle.addr1))
  730.   == SAMESTRING  ||
  731.   strncmp(msgBuf.mbaddr, NetStyle.addr2, strLen(NetStyle.addr2))
  732.   == SAMESTRING  ||
  733.   strncmp(msgBuf.mbaddr, NetStyle.addr3, strLen(NetStyle.addr3))
  734.   == SAMESTRING) &&
  735.   RoutePath(LOC_NET, msgBuf.mbaddr)     != thisNet       &&
  736.   RoutePath(NON_LOC_NET, msgBuf.mbaddr) != thisNet)
  737.     {
  738.     prNetStyle(FALSE, NetStyle.sendfunc, TRUE, "");
  739.     temp = atol(msgBuf.mbId);
  740.     NetStyle.HiSent = max(NetStyle.HiSent,temp);
  741.     return TRUE;
  742.  
  743.     }
  744.   return FALSE;
  745.  
  746.   }
  747. /*
  748. * RoutePath()
  749. *
  750. * This function returns the number of the node that routed this msg to here.
  751. * If the msg was not routed in from a BackBone, then return ERROR, which will
  752. * never match another node's #.
  753. *
  754. * 88Oct13: Now simply check for msg origin, assume if one exists that it
  755. * should be checked.  Don't remember why it is restricted to only
  756. * BACKBONE-routed msgs.  Doesn't seem necessary.
  757. */
  758. int RoutePath(char *rp, char *str)
  759.   {
  760.   if (strncmp(rp, str, strLen(rp)) == SAMESTRING)
  761.     {
  762.     if (strLen(str) != strLen(rp)) /* prevent return of 0 */
  763.     return atoi(str + 2);
  764.  
  765.     }
  766.   return ERROR;
  767.  
  768.   }
  769. /*
  770. * doSendFiles()
  771. *
  772. * This function will send files to a victim.
  773. */
  774. void doSendFiles()
  775.   {
  776.   extern char       *READ_ANY;
  777.   struct   fl_send  theFiles;
  778.   SYS_FILE          sdFile;
  779.   char              temp[8];
  780.   FILE              *fd;
  781.   ITL_optimize(FALSE);    /* try for better protocol */
  782.   sPrintf(temp, "%d.sfl", thisNet);
  783.   makeSysName(sdFile, temp, &cfg.netArea);
  784.   if ((fd = safeopen(sdFile, READ_ANY)) == NULL)
  785.     {
  786.     sPrintf(msgBuf.mbtext, "Couldn't open send file %s for %s!",
  787.     sdFile,netBuf.netName);
  788.     netResult(msgBuf.mbtext);
  789.     netBuf.nbflags.send_files = FALSE;
  790.  
  791.     }
  792.   else
  793.     {
  794.     while (getSLNet(theFiles, fd) && haveCarrier)
  795.       {
  796.       sysSendFiles(&theFiles);
  797.  
  798.       }
  799.     fclose(fd);
  800.     if (haveCarrier)
  801.       {
  802.       /* if no carrier, was an error during transmit */
  803.       unlink(sdFile);
  804.       netBuf.nbflags.send_files = FALSE;
  805.  
  806.       }
  807.  
  808.     }
  809.  
  810.   }
  811. /*
  812. * netSendFile()
  813. *
  814. * This function will send a file to another system via net.
  815. */
  816. void netSendFile(DirEntry *fn)
  817.   {
  818.   extern char     *READ_ANY;
  819.   struct cmd_data cmds;
  820.   char            mess[140];
  821.   if (!gotCarrier()) return ;
  822.   if( logNetResults && netDebug )splitF(netLog, "Send File: %s\n", fn->unambig);
  823.   zero_struct(cmds);
  824.   cmds.command = SEND_FILE;
  825.   strCpy(cmds.fields[0], fn->unambig);
  826.   sPrintf(cmds.fields[1], "%ld", (fn->FileSize + SECTSIZE - 1) / SECTSIZE);
  827.   sPrintf(cmds.fields[2], "%ld", fn->FileSize);
  828.   if (!sendNetCommand(&cmds, "send file"))
  829.     {
  830.     if (haveCarrier)
  831.       {
  832.       strCpy(mess, "%s reports: ");
  833.       strCat(mess, RecBuf + 1);
  834.       no_good(mess, FALSE);
  835.  
  836.       }
  837.  
  838.     }
  839.   else
  840.     {
  841.     SendHostFile(fn->unambig);
  842.     if (haveCarrier)
  843.       {
  844.       sPrintf(msgBuf.mbtext, "%s sent to %s.", fn->unambig,
  845.       netBuf.netName);
  846.       netResult(msgBuf.mbtext);
  847.  
  848.       }
  849.  
  850.     }
  851.  
  852.   }
  853. extern FILE *upfd;
  854. /*
  855. * askFiles()
  856. *
  857. * This function will ask for file(s) from caller.
  858. */
  859. static void fl_req_free(struct fl_req *d);
  860. void askFiles()
  861.   {
  862.   label    data2;
  863.   SYS_FILE dataFl;
  864.   char     mess[130];
  865.   char     ambiguous;
  866.   int      result = ITL_SUCCESS;
  867.   FILE     *temp;
  868.   struct   cmd_data cmds;
  869.   struct   fl_req file_data, *list;
  870.   SListBase Failed =
  871.     {
  872.     NULL, NULL, NULL, fl_req_free, NULL
  873.  
  874.     };
  875.   extern char *READ_ANY, *WRITE_ANY;
  876.   if (!gotCarrier())
  877.     {
  878.     modStat = haveCarrier = FALSE;
  879.     return ;
  880.  
  881.     }
  882.   sPrintf(data2, "%d.rfl", thisNet);
  883.   makeSysName(dataFl, data2, &cfg.netArea);
  884.   temp = safeopen(dataFl, READ_ANY);
  885.   if (temp == NULL)
  886.     {
  887.     no_good("Couldn't open room request file for %s", FALSE);
  888.     netBuf.nbflags.room_files = FALSE;
  889.  
  890.     }
  891.   else
  892.     {
  893.     ITL_optimize(FALSE);    /* try for better protocol */
  894.     while ( result == ITL_SUCCESS &&
  895.     fread(&file_data, sizeof (file_data), 1, temp) == 1 &&
  896.     gotCarrier() && result == ITL_SUCCESS)
  897.       {
  898.       if (netSetNewArea(&file_data.flArea))
  899.         {
  900.         zero_struct(cmds);
  901.         ambiguous = !(strchr(file_data.roomfile, '*') == NULL &&
  902.         strchr(file_data.roomfile, '?') == NULL);
  903.         cmds.command = (!ambiguous) ? R_FILE_REQ : A_FILE_REQ;
  904.         strCpy(cmds.fields[0], file_data.room);
  905.         strCpy(cmds.fields[1], file_data.roomfile);
  906.         if( logNetResults )splitF(netLog, "Requesting %s in %s\n", file_data.roomfile,
  907.         file_data.room);
  908.         if (!sendNetCommand(&cmds,
  909.         (!ambiguous) ? "single file request" :
  910.         "multiple file request"))
  911.           {
  912.           sPrintf(mess, "%%s reports %s for file %s in %s.", RecBuf+1,
  913.           file_data.roomfile, file_data.room);
  914.           no_good(mess, FALSE);
  915.  
  916.           }
  917.         else
  918.           {
  919.           if (ambiguous)
  920.           result = multiReceive(&file_data);
  921.           else
  922.             {
  923.             if ((result = ITL_Receive(file_data.filename, FALSE,
  924.             TRUE, putFLChar, fclose)) == ITL_SUCCESS)
  925.               {
  926.               sPrintf(msgBuf.mbtext,
  927.               "File '%s' received from %s (stored in directory %s).",
  928.               file_data.filename, netBuf.netName,
  929.               prtNetArea(&file_data.flArea));
  930.               netResult(msgBuf.mbtext);
  931.  
  932.               }
  933.  
  934.             }
  935.  
  936.           }
  937.  
  938.         }
  939.       homeSpace();
  940.  
  941.       }
  942.     if (gotCarrier())
  943.       {
  944.       fclose(temp);
  945.       unlink(dataFl);
  946.       netBuf.nbflags.room_files = FALSE;
  947.  
  948.       }
  949.     else
  950.       {
  951.       haveCarrier = modStat = FALSE;
  952.       /* Now find out what we didn't get and set up a new request queue */
  953.       do
  954.         {
  955.         /* use do loop to get the one it failed in */
  956.         list = GetDynamic(sizeof *list);
  957.         copy_struct(file_data, (*list));
  958.         AddData(&Failed, list, NULL, FALSE);
  959.  
  960.         }
  961.       while (fread(&file_data, sizeof (file_data), 1, temp) == 1);
  962.       fclose(temp);
  963.       unlink(dataFl);
  964.       upfd = fopen(dataFl, WRITE_ANY);
  965.       KillList(&Failed);
  966.       fclose(upfd);
  967.  
  968.       }
  969.  
  970.     }
  971.  
  972.   }
  973. /*
  974. * fl_req_free()
  975. *
  976. * This will write and free a file request.
  977. */
  978. static void fl_req_free(struct fl_req *d)
  979.   {
  980.   if (upfd != NULL) fwrite(d, sizeof *d, 1, upfd);
  981.   free(d);
  982.  
  983.   }
  984. /*
  985. * multiReceive()
  986. *
  987. * This function will receive multiple files.
  988. */
  989. char multiReceive(struct fl_req *file_data)
  990.   {
  991.   char        first = 1;
  992.   extern char *WRITE_ANY;
  993.   sPrintf(msgBuf.mbtext,
  994.   "Following files received from %s in response to request for %s from %s: ",
  995.   netBuf.netName, file_data->roomfile, file_data->room);
  996.   do
  997.     {
  998.     if (ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose) != ITL_SUCCESS ||
  999.     !gotCarrier()) return ITL_BAD_TRANS;
  1000.     if (RecBuf[0] == 0)
  1001.       {
  1002.       /* Last file name       */
  1003.       sPrintf(lbyte(msgBuf.mbtext), " (stored in directory %s).",
  1004.       prtNetArea(&file_data->flArea));
  1005.       netResult(msgBuf.mbtext);
  1006.       return ITL_SUCCESS;
  1007.  
  1008.       }
  1009.     if (!first)
  1010.     strCat(msgBuf.mbtext, ", ");
  1011.     else
  1012.     first = FALSE;
  1013.     strCat(msgBuf.mbtext, RecBuf);
  1014.     if (ITL_Receive(RecBuf, FALSE, TRUE, putFLChar, fclose) != ITL_SUCCESS
  1015.     || !gotCarrier()) return ITL_BAD_TRANS;
  1016.  
  1017.     }
  1018.   while (1);
  1019.   return ITL_SUCCESS;
  1020.  
  1021.   }
  1022. /*
  1023. * sendNetCommand()
  1024. *
  1025. * This sends a command to the receiver.
  1026. */
  1027. char sendNetCommand(struct cmd_data *cmds, char *error)
  1028.   {
  1029.   char errMsg[100];
  1030.   int  count;
  1031.   if (cfg.BoolFlags.debug && netDebug )
  1032.     {
  1033.     splitF(netLog, "Sending Command: %d\n", cmds->command);
  1034.     splitF(netLog, " Field[0]: %s\n", cmds->fields[0]);
  1035.     splitF(netLog, " Field[1]: %s\n", cmds->fields[1]);
  1036.     splitF(netLog, " Field[2]: %s\n", cmds->fields[2]);
  1037.     splitF(netLog, " Field[3]: %s\n", cmds->fields[3]);
  1038.     };
  1039.  
  1040.   if (!ITL_Send(STARTUP))
  1041.     {
  1042.     sPrintf(errMsg, "Link failure for %s (system: %%s).", error);
  1043.     if (cmds->command != HANGUP) no_good(errMsg, TRUE);
  1044.     killConnection();
  1045.     return FALSE;
  1046.  
  1047.     }
  1048.   sendITLchar(cmds->command);
  1049.   for (count = 0; count < 4; count++)
  1050.     {
  1051.     if (cmds->fields[count][0])
  1052.       {
  1053.       mTrPrintf("%s", cmds->fields[count]);
  1054.  
  1055.       }
  1056.  
  1057.     }
  1058.   sendITLchar(0);
  1059.   ITL_Send(FINISH);
  1060.   if (cmds->command == HANGUP && !inReceive) return TRUE;
  1061.   ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  1062.   if (RecBuf[0] == BAD || !gotCarrier()) return FALSE;
  1063.   return TRUE;
  1064.  
  1065.   }
  1066. /*
  1067. * sendHangUp()
  1068. *
  1069. * This sends the hangup command to receiver.
  1070. */
  1071. void sendHangUp()
  1072.   {
  1073.   struct cmd_data cmds;
  1074.   if (!gotCarrier())
  1075.     {
  1076.     modStat = haveCarrier = FALSE;
  1077.     return ;
  1078.  
  1079.     }
  1080.   zero_struct(cmds);
  1081.   cmds.command = HANGUP;
  1082.   sendNetCommand(&cmds, "HANGUP");
  1083.  
  1084.   }
  1085. /*
  1086. * no_good()
  1087. *
  1088. * This handles error messages when something really bad happens.
  1089. */
  1090. void no_good(char *str, char hup)
  1091.   {
  1092.   sPrintf(msgBuf.mbtext, str, netBuf.netName);
  1093.   if (hup)
  1094.     {
  1095.     killConnection();
  1096.  
  1097.     }
  1098.   netResult(msgBuf.mbtext);
  1099.  
  1100.   }
  1101. /*
  1102. * s_m_n()
  1103. *
  1104. * This sends mail normal (non-route mail).
  1105. */
  1106. int s_m_n()
  1107.   {
  1108.   FILE     *ptrs;
  1109.   label    fntemp;
  1110.   SYS_FILE fn;
  1111.   int      messCount = 0;
  1112.   struct   netMLstruct buf;
  1113.   extern char *READ_ANY;
  1114.   sPrintf(fntemp, "%d.ml", thisNet);
  1115.   makeSysName(fn, fntemp, &cfg.netArea);
  1116.   if ((ptrs = safeopen(fn, READ_ANY)) == NULL)
  1117.     {
  1118.     if (netBuf.nbflags.normal_mail)
  1119.       {
  1120.       sPrintf(msgBuf.mbtext, "No mail file to send to %s?",
  1121.       netBuf.netName);
  1122.       netResult(msgBuf.mbtext);
  1123.  
  1124.       }
  1125.     return 0;
  1126.  
  1127.     }
  1128.   while (getMLNet(ptrs, buf) && TrError == TRAN_SUCCESS)
  1129.     {
  1130.     if (findMessage(buf.ML_loc, buf.ML_id, TRUE))
  1131.       {
  1132.       if (netDebug)
  1133.         {
  1134.         MessageBuffer *msg = &msgBuf;
  1135.         splitF(netLog, "Message %6d Sector ID: %6d Author:%s\n",  msg->mbheadChar, msg->mbheadSector, msg->mbauth);
  1136.         splitF(netLog, "Date:%20s Time:%20s Local Id:%20s\n",  msg->mbdate,  msg-> mbtime,  msg-> mbId);
  1137.         splitF(netLog, "Human:%20s ID:%20s Room:%20s\n",  msg->mboname,  msg->mborig,  msg->mbroom);
  1138.         splitF(netLog, "Origin:%20s To:%20s\n",  msg->mbsrcId,  msg->mbto);
  1139.         splitF(netLog, "Route:%s\n", msg->mbaddr);
  1140.         splitF(netLog, "OtherNet:%s\n",msg->mbOther);
  1141.         splitF(netLog, "reply:%20s Domain:%20s\n",msg->mbreply, msg->mbdomain);
  1142.         }
  1143.       prNetStyle(0, sendITLchar, TRUE, netBuf.netName);
  1144.       messCount++;
  1145.  
  1146.       }
  1147.  
  1148.     }
  1149.   fclose(ptrs);
  1150.   if (TrError == TRAN_SUCCESS)
  1151.     {
  1152.     unlink(fn);
  1153.     return messCount;
  1154.  
  1155.     }
  1156.   killConnection();
  1157.   if( logNetResults )splitF(netLog, "\nFailed transferring mail!\n");
  1158.   return 0;
  1159.  
  1160.   }
  1161. /*
  1162. * SendHostFile()
  1163. *
  1164. * This function will send a file to the other system.
  1165. */
  1166. void SendHostFile(char *fn)
  1167.   {
  1168.   int  success;
  1169.   FILE *fd;
  1170.   extern int errno;
  1171.   extern char *READ_ANY;
  1172.   success = ((fd = safeopen(fn, READ_ANY)) != NULL);
  1173.   if (ITL_Send(STARTUP))
  1174.     {
  1175.     if (!success) mTrPrintf("System error failure, this is a bogus file.");
  1176.     else
  1177.       {
  1178.       SendThatDamnFile(fd, sendITLchar);
  1179.  
  1180.       }
  1181.     ITL_Send(FINISH);
  1182.  
  1183.     }
  1184.   if (!success)
  1185.     {
  1186.     sPrintf(msgBuf.mbtext, "System error! Couldn't open %s for %s, errno %d.",
  1187.     fn, netBuf.netName, errno);
  1188.     netResult(msgBuf.mbtext);
  1189.  
  1190.     }
  1191.  
  1192.   }
  1193.